﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace MVVMToolkitLesson
{
    public partial class MainViewModel : ObservableValidator
    {
        //1.基本通知属性
        private string _value;

        public string Value
        {
            get { return _value; }
            set
            {
                SetProperty<string>(ref _value, value);
                //_value = value;
                //this.OnPropertyChanged(); //这两行注释的代码与上面一行代码等价
            }
        }

        //2、业务需求
        //从API接口获取相关数据
        //这个数据以Json/XML形式进行返回
        //拿到数据后，进行反序列化，通过程序中的实体/模型进行接收
        //实体：属性需要与Json中的名称相同
        //可能实体里的数据被多个Model进行引用；也有可能一个Model中需要多个实体数据
        //转换过程：实体到Model的数据转换过程

        UserEntity userEntity = new UserEntity();

        private string _name;

        public string UserName
        {
            get { return _name; }
            set
            {
                SetProperty<UserEntity,string>(
                    userEntity.userName, 
                    value, 
                    userEntity, 
                    (entity, value) => entity.userName = value);
                //_value = value;
                //this.OnPropertyChanged(); //这两行注释的代码与上面一行代码等价
            }
        }

        //3、有一个属性，获取一个值赋值给这个属性
        //问题：获取值的过程异步，耗时操作，

        private TaskNotifier<int> _taskValue;

        public Task<int> TaskValue
        {
            get { return _taskValue; }
            set
            {
                SetPropertyAndNotifyOnCompletion(ref _taskValue, value);
            }
        }

        public RelayCommand ButtonCommand { get; set; }

        public AsyncRelayCommand ButtonAsyncCommand { get; set; }

        public MainViewModel()
        {
            ButtonCommand = new RelayCommand(ButtonClick);
            ButtonAsyncCommand = new AsyncRelayCommand(ButtonAsyncClick);
            //消息订阅
            WeakReferenceMessenger.Default.Register<string>(this, (obj, str) =>
            {
                MessageBox.Show(str);
            });
            WeakReferenceMessenger.Default.Register<string,int>(this, 123,(obj, str) =>
            {
                MessageBox.Show(str);
            });

            //WeakReferenceMessenger.Default.UnregisterAll(this);
        }

        void ButtonClick()
        {
            WeakReferenceMessenger.Default.Send("Hello, world!");
            WeakReferenceMessenger.Default.Send<string, int>("带token的消息传递", 123);
        }


        //关于特性的使用
        //1.ObservableProperty：可观察的属性，通知属性
        [ObservableProperty]
        [NotifyPropertyChangedFor("FullName")] //修改此属性的时候通知指定属性
        public string name;
        //上面两行代码的写法可以直接在页面上绑定Name属性
        //接下来 如何处理这个字段/属性的变化过程呢？
        partial void OnNameChanged(string? oldValue, string? newValue)
        {
            //处理字段变化过程
        }

        partial void OnNameChanging(string? oldValue, string? newValue)
        {
            //当字段开始变化时执行
        }

        /// <summary>
        /// 页面是FullName属性
        /// </summary>
        private string FullName => "zx" + name;


        [ObservableProperty]
        [NotifyDataErrorInfo]//关键特性校验
        [Required]
        [MinLength(2,ErrorMessage = "最小长度为2")]
        private string inputValue = "123";
        //这个字段对应的属性 需要进行数据校验
        //1.类继承ObservableValidator
        //2.给字段添加相关校验特性


        /// <summary>
        /// 自动生成一个命令属性
        /// public RelayCommand DoButtonCommand { get; set;}
        /// </summary>
        [RelayCommand]
        private void DoButton()
        {
            MessageBox.Show("按钮被点击了");
        }

        Task ButtonAsyncClick()
        {
            return Task.Run(() =>
            {

            });
        }
    }
}
